package mitlab.seg.ner.domain;

import org.nlpcn.commons.lang.util.StringUtil;
import mitlab.seg.crf_seg.util.MathUtil;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class Term implements Serializable {
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  // 当前词
  private String name;
  //
  private String realName;
  // 当前词的起始位置
  private int offe;
  // 词性列表
  private TermNatures termNatures = TermNatures.NULL;
  // 词性列表
  private SegItem item = SegItem.NULL;
  // 同一行内数据
  private Term next;
  // 分数
  private double score = 0;
  // 本身分数
  private double selfScore = 1;
  // 起始位置
  private Term from;
  // 到达位置
  private Term to;
  // 本身这个term的词性.需要在词性识别之后才会有值,默认是空
  private Nature nature = Nature.NULL;
  // 是否是一个新词
  private boolean newWord;
  // 同义词
  private List<String> synonyms;


  private List<Term> subTerm = null;

  public Term(String name, int offe, SegItem item) {
    super();
    this.name = name;
    this.offe = offe;
    this.item = item;
    if (item.termNatures != null) {
      this.termNatures = item.termNatures;
      if (termNatures.nature != null) {
        this.nature = termNatures.nature;
      }
    }
  }

  public Term(String name, int offe) {
    this.realName = name;
    this.offe = offe;
  }

  public Term(String name, int offe, TermNatures termNatures) {
    super();
    this.name = name;
    this.offe = offe;
    this.termNatures = termNatures;
    if (termNatures.nature != null) {
      this.nature = termNatures.nature;
    }
  }

  public Term(String name, int offe, String natureStr, int natureFreq) {
    super();
    this.name = name;
    this.offe = offe;
    TermNature termNature = new TermNature(natureStr, natureFreq);
    this.nature = termNature.nature;
    this.termNatures = new TermNatures(termNature);
  }

  // 可以到达的位置
  public int toValue() {
    return offe + name.length();
  }

  public int getOffe() {
    return offe;
  }

  public void setOffe(int offe) {
    this.offe = offe;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  /**
   * 核心构建最优的路径
   *
   * @param from
   * @param relationMap
   */
  public void setPathScore(Term from, Map<String, Double> relationMap) {
    // 维特比进行最优路径的构建
    double score = MathUtil.compuScore(from, this, relationMap);
    if (this.from == null || this.score == 0 || this.score >= score) {
      this.setFromAndScore(from, score);
    }
  }

  /**
   * 核心分数的最优的路径,越小越好
   *
   * @param from
   */
  public void setPathSelfScore(Term from, boolean asc) {
    double score = this.selfScore + from.score;
    // 维特比进行最优路径的构建
    if (this.from == null) {
      this.setFromAndScore(from, score);
    } else {
      if ((this.score > score) == asc) {
        this.setFromAndScore(from, score);
      }

    }
  }

  private void setFromAndScore(Term from, double score) {
    this.from = from;
    this.score = score;
  }

  /**
   * 进行term合并
   *
   * @param to
   */
  public Term merage(Term to) {
    this.name = this.name + to.getName();
    if (StringUtil.isNotBlank(this.realName) && StringUtil.isNotBlank(to.getRealName())) {
      this.realName = this.realName + to.getRealName();
    }
    this.setTo(to.to);
    return this;
  }

  /**
   * 进行term合并,能合并空白字符
   *
   * @param to
   */
  public Term merageWithBlank(Term to) {
    this.name = this.name + to.getName();
    this.realName = this.realName + to.getRealName();
    this.setTo(to.to);
    return this;
  }

  /**
   * 更新偏移量
   *
   * @param offe
   */
  public void updateOffe(int offe) {
    this.offe += offe;
  }

  public Term next() {
    return next;
  }

  /**
   * 返回他自己
   *
   * @param next 设置他的下一个
   * @return
   */
  public Term setNext(Term next) {
    this.next = next;
    return this;
  }

  public Term from() {
    return from;
  }

  public Term to() {
    return to;
  }

  public void setFrom(Term from) {
    this.from = from;
  }

  public void setTo(Term to) {
    this.to = to;
  }

  /**
   * 获得这个term的所有词性
   *
   * @return
   */
  public TermNatures termNatures() {
    return termNatures;
  }

  public void setNature(Nature nature) {
    this.nature = nature;
  }

  /**
   * 获得这个词的词性.词性计算后才可生效
   *
   * @return
   */
  public Nature natrue() {
    return nature;
  }

  public String getNatureStr() {
    return nature.natureStr;
  }

  @Override
  public String toString() {
    if ("null".equals(nature.natureStr)) {
      return this.getRealName();
    }
    return this.getRealName() + "/" + nature.natureStr;
  }

  /**
   * 将term的所有分数置为0
   */
  public void clearScore() {
    this.score = 0;
    this.selfScore = 0;
  }

  public void setSubTerm(List<Term> subTerm) {
    this.subTerm = subTerm;
  }

  public List<Term> getSubTerm() {
    return subTerm;
  }

  public String getRealName() {
    if (realName == null) {
      return name;
    }
    return realName;
  }

  public String getRealNameIfnull() {
    return realName;
  }

  public void setRealName(String realName) {
    this.realName = realName;
  }

  public double score() {
    return this.score;
  }

  public void score(double score) {
    this.score = score;
  }

  public double selfScore() {
    return this.selfScore;
  }

  public void selfScore(double selfScore) {
    this.selfScore = selfScore;
  }

  public SegItem item() {
    return this.item;
  }

  public boolean isNewWord() {
    return newWord;
  }

  public void setNewWord(boolean newWord) {
    this.newWord = newWord;
  }

  public void updateTermNaturesAndNature(TermNatures termNatures) {
    this.termNatures = termNatures;
    this.nature = termNatures.nature;
  }

  public List<String> getSynonyms() {
    return synonyms;
  }

  public void setSynonyms(List<String> synonyms) {
    this.synonyms = synonyms;
  }

}
